import pygame
import random

# 初始化pygame
pygame.init()

# 颜色定义
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GRAY = (128, 128, 128)
COLORS = [
    (0, 255, 255),  # I - 青色
    (0, 0, 255),  # J - 蓝色
    (255, 165, 0),  # L - 橙色
    (255, 255, 0),  # O - 黄色
    (0, 255, 0),  # S - 绿色
    (128, 0, 128),  # T - 紫色
    (255, 0, 0)  # Z - 红色
]

# 游戏设置
BLOCK_SIZE = 30
GRID_WIDTH = 10
GRID_HEIGHT = 20
SCREEN_WIDTH = BLOCK_SIZE * (GRID_WIDTH + 6)
SCREEN_HEIGHT = BLOCK_SIZE * GRID_HEIGHT
GAME_AREA_LEFT = BLOCK_SIZE

# 方块形状定义
SHAPES = [
    [[1, 1, 1, 1]],  # I

    [[1, 0, 0],
     [1, 1, 1]],  # J

    [[0, 0, 1],
     [1, 1, 1]],  # L

    [[1, 1],
     [1, 1]],  # O

    [[0, 1, 1],
     [1, 1, 0]],  # S

    [[0, 1, 0],
     [1, 1, 1]],  # T

    [[1, 1, 0],
     [0, 1, 1]]  # Z
]

# 创建游戏窗口
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("俄罗斯方块")

clock = pygame.time.Clock()


class Tetromino:
    def __init__(self, x, y, shape):
        self.x = x
        self.y = y
        self.shape = shape
        self.color = COLORS[SHAPES.index(shape)]
        self.rotation = 0

    def rotate(self):
        # 转置矩阵然后反转每一行来实现旋转
        rows = len(self.shape)
        cols = len(self.shape[0])
        rotated = [[0 for _ in range(rows)] for _ in range(cols)]

        for r in range(rows):
            for c in range(cols):
                rotated[c][rows - 1 - r] = self.shape[r][c]

        return rotated


class TetrisGame:
    def __init__(self):
        self.grid = [[0 for _ in range(GRID_WIDTH)] for _ in range(GRID_HEIGHT)]
        self.current_piece = self.new_piece()
        self.next_piece = self.new_piece()
        self.game_over = False
        self.score = 0
        self.level = 1
        self.fall_speed = 0.5  # 秒
        self.fall_time = 0

    def new_piece(self):
        shape = random.choice(SHAPES)
        return Tetromino(GRID_WIDTH // 2 - len(shape[0]) // 2, 0, shape)

    def valid_move(self, piece, x_offset=0, y_offset=0, rotated_shape=None):
        shape_to_check = rotated_shape if rotated_shape else piece.shape
        for y, row in enumerate(shape_to_check):
            for x, cell in enumerate(row):
                if cell:
                    new_x = piece.x + x + x_offset
                    new_y = piece.y + y + y_offset
                    if (new_x < 0 or new_x >= GRID_WIDTH or
                            new_y >= GRID_HEIGHT or
                            (new_y >= 0 and self.grid[new_y][new_x])):
                        return False
        return True

    def lock_piece(self):
        for y, row in enumerate(self.current_piece.shape):
            for x, cell in enumerate(row):
                if cell:
                    self.grid[self.current_piece.y + y][self.current_piece.x + x] = self.current_piece.color

        # 检查是否有完整的行
        self.clear_lines()

        # 生成新方块
        self.current_piece = self.next_piece
        self.next_piece = self.new_piece()

        # 检查游戏是否结束
        if not self.valid_move(self.current_piece):
            self.game_over = True

    def clear_lines(self):
        lines_cleared = 0
        for y in range(GRID_HEIGHT):
            if all(self.grid[y]):
                lines_cleared += 1
                # 移动上面的行下来
                for y2 in range(y, 0, -1):
                    self.grid[y2] = self.grid[y2 - 1][:]
                self.grid[0] = [0 for _ in range(GRID_WIDTH)]

        # 更新分数
        if lines_cleared == 1:
            self.score += 100 * self.level
        elif lines_cleared == 2:
            self.score += 300 * self.level
        elif lines_cleared == 3:
            self.score += 500 * self.level
        elif lines_cleared == 4:
            self.score += 800 * self.level

        # 更新等级 (每清除10行升一级)
        self.level = 1 + self.score // 1000
        self.fall_speed = max(0.05, 0.5 - (self.level - 1) * 0.05)

    def update(self, delta_time):
        if self.game_over:
            return

        self.fall_time += delta_time
        if self.fall_time >= self.fall_speed:
            self.fall_time = 0
            if self.valid_move(self.current_piece, y_offset=1):
                self.current_piece.y += 1
            else:
                self.lock_piece()

    def draw(self):
        # 绘制游戏区域背景
        pygame.draw.rect(screen, GRAY, (GAME_AREA_LEFT, 0, BLOCK_SIZE * GRID_WIDTH, SCREEN_HEIGHT))
        pygame.draw.rect(screen, BLACK, (GAME_AREA_LEFT, 0, BLOCK_SIZE * GRID_WIDTH, SCREEN_HEIGHT), 2)

        # 绘制网格
        for x in range(GRID_WIDTH):
            for y in range(GRID_HEIGHT):
                pygame.draw.rect(screen, BLACK,
                                 (GAME_AREA_LEFT + x * BLOCK_SIZE, y * BLOCK_SIZE,
                                  BLOCK_SIZE, BLOCK_SIZE), 1)

        # 绘制已落下的方块
        for y in range(GRID_HEIGHT):
            for x in range(GRID_WIDTH):
                if self.grid[y][x]:
                    pygame.draw.rect(screen, self.grid[y][x],
                                     (GAME_AREA_LEFT + x * BLOCK_SIZE + 1,
                                      y * BLOCK_SIZE + 1,
                                      BLOCK_SIZE - 2, BLOCK_SIZE - 2))

        # 绘制当前方块
        if not self.game_over:
            for y, row in enumerate(self.current_piece.shape):
                for x, cell in enumerate(row):
                    if cell:
                        pygame.draw.rect(screen, self.current_piece.color,
                                         (GAME_AREA_LEFT + (self.current_piece.x + x) * BLOCK_SIZE + 1,
                                          (self.current_piece.y + y) * BLOCK_SIZE + 1,
                                          BLOCK_SIZE - 2, BLOCK_SIZE - 2))

        # 绘制下一个方块预览
        next_x = GAME_AREA_LEFT + GRID_WIDTH * BLOCK_SIZE + 20
        next_y = 50

        pygame.draw.rect(screen, WHITE, (next_x, next_y, BLOCK_SIZE * 4, BLOCK_SIZE * 4))
        pygame.draw.rect(screen, BLACK, (next_x, next_y, BLOCK_SIZE * 4, BLOCK_SIZE * 4), 2)

        # 计算下一个方块的居中位置
        shape_width = len(self.next_piece.shape[0])
        shape_height = len(self.next_piece.shape)
        offset_x = (4 - shape_width) // 2
        offset_y = (4 - shape_height) // 2

        for y, row in enumerate(self.next_piece.shape):
            for x, cell in enumerate(row):
                if cell:
                    pygame.draw.rect(screen, self.next_piece.color,
                                     (next_x + (offset_x + x) * BLOCK_SIZE + 1,
                                      next_y + (offset_y + y) * BLOCK_SIZE + 1,
                                      BLOCK_SIZE - 2, BLOCK_SIZE - 2))

        # 绘制分数和等级
        font = pygame.font.SysFont('Arial', 20)
        score_text = font.render(f"分数: {self.score}", True, WHITE)
        level_text = font.render(f"等级: {self.level}", True, WHITE)

        screen.blit(score_text, (next_x, 150))
        screen.blit(level_text, (next_x, 180))

        # 游戏结束提示
        if self.game_over:
            font = pygame.font.SysFont('Arial', 40)
            game_over_text = font.render("游戏结束!", True, (255, 0, 0))
            text_rect = game_over_text.get_rect(center=(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2))
            screen.blit(game_over_text, text_rect)

            restart_text = font.render("按R重新开始", True, WHITE)
            restart_rect = restart_text.get_rect(center=(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2 + 50))
            screen.blit(restart_text, restart_rect)


def main():
    game = TetrisGame()
    running = True

    while running:
        delta_time = clock.tick(60) / 1000.0  # 转换为秒

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False

            if not game.game_over:
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_LEFT:
                        if game.valid_move(game.current_piece, x_offset=-1):
                            game.current_piece.x -= 1
                    elif event.key == pygame.K_RIGHT:
                        if game.valid_move(game.current_piece, x_offset=1):
                            game.current_piece.x += 1
                    elif event.key == pygame.K_DOWN:
                        if game.valid_move(game.current_piece, y_offset=1):
                            game.current_piece.y += 1
                    elif event.key == pygame.K_UP:
                        rotated_shape = game.current_piece.rotate()
                        if game.valid_move(game.current_piece, rotated_shape=rotated_shape):
                            game.current_piece.shape = rotated_shape
                    elif event.key == pygame.K_SPACE:
                        # 硬降落
                        while game.valid_move(game.current_piece, y_offset=1):
                            game.current_piece.y += 1
                        game.lock_piece()
            else:
                if event.type == pygame.KEYDOWN and event.key == pygame.K_r:
                    game = TetrisGame()  # 重新开始游戏

        # 自动下落
        keys = pygame.key.get_pressed()
        if keys[pygame.K_DOWN]:
            game.update(delta_time * 5)  # 按住下键时加速下落
        else:
            game.update(delta_time)

        # 绘制
        screen.fill(BLACK)
        game.draw()
        pygame.display.flip()

    pygame.quit()


if __name__ == "__main__":
    main()